<script lang="ts" setup>
import { getActorData } from "@@/apis/video/actor"
import { batchRemoveVideoData, removeVideoData } from "@@/apis/video/index"
import { getSeriesData } from "@@/apis/video/series"
import { checkPermission } from "@@/utils/permission"
import { Delete, Plus, WarningFilled } from "@element-plus/icons-vue"
import { onMounted, ref } from "vue"
import { resolutionOptions, subtitleOptions, toOption, videoTypeOptions } from "./constants"
import { useForm } from "./useForm"
import { useTable } from "./useTable"

// 新增：定义 baseUrl 变量
const baseUrl = import.meta.env.VITE_BASE_API_URL

// 表格与分页
const {
  tableData,
  searchParams,
  currentPage,
  pageSize,
  total,
  fetchData,
  handlePageChange,
  handleSizeChange,
  getSearchParams
} = useTable()

// 表单相关
const {
  formData,
  formRules,
  formDataRef,
  addDialogVisible,
  isEdit,
  showDialog,
  submitForm,
  closeDialog,
  fileList,
  fileChange
} = useForm(fetchData)

// 行选择，禁用 id 为 1,2 的行
const selectable = (row: any) => ![1, 2].includes(row.id)

const filterMulti = ref(false)

// 编辑弹窗初始化
function handleEdit(row: any) {
  fileList.value = row.coverUrl
    ? row.coverUrl.split(";").map((file: string) => ({ name: file, url: baseUrl + file }))
    : []
  formData.value = { ...row, actorList: row.actor ? row.actor.split("、") : [] }
  isEdit.value = true
  showDialog()
}

// 多选行
const selectedRows = ref<any[]>([])
const handleSelectionChange = (val: any[]) => selectedRows.value = val

// 通用确认弹窗
async function confirmAction(message: string, action: () => Promise<void>) {
  try {
    await ElMessageBox.confirm(message, "提示！", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning"
    })
    await action()
  } catch { }
}

// 删除单条
async function handleRemove(row: any) {
  await confirmAction("确认删除吗?", async () => {
    await removeVideoData(row.id)
    fetchData()
    ElMessage.success("删除成功！")
  })
}

// 批量删除
async function batchDelete() {
  if (!selectedRows.value.length) return ElMessage.warning("请选择要删除的项")
  await confirmAction("确认删除吗?", async () => {
    await batchRemoveVideoData({ ids: selectedRows.value.map(item => item.id) })
    fetchData()
    ElMessage.success("删除成功！")
  })
}

// 移除上传文件
function removeFile(file: any) {
  fileList.value = fileList.value.filter(item => item.name !== file.name)
}

// 通用下载方法
function downloadByUrl(url: string) {
  try {
    if (!url) {
      console.error("下载链接不能为空")
      return
    }

    if (filterMulti.value) {
      // 判断URL是否已包含查询参数，使用?或&进行拼接
      const separator = url.includes("?") ? "&" : "?"
      url = `${url}${separator}filterMulti=1`
    }

    // 创建隐藏的下载链接
    const link = document.createElement("a")
    link.href = url
    link.style.display = "none"
    link.target = "_blank"

    // 添加到DOM中并触发点击
    document.body.appendChild(link)
    link.click()

    // 清理DOM元素
    document.body.removeChild(link)
  } catch (error) {
    console.error("下载失败:", error)
  }
}

// 下载文档
const downloadDoc = () => downloadByUrl(`${baseUrl}/video/download-doc`)
// 下载全部资源
const downloadAllDoc = () => downloadByUrl(`${baseUrl}/video/download`)

// 校验封面有效性（替换为 Image 对象方式，避免 CORS 问题）
async function validateCoverList(list: any[], chunkSize = 5) {
  let invalidCount = 0
  const validateCover = (item: any) => {
    return new Promise<void>((resolve) => {
      if (!item.coverUrl || typeof item.coverUrl !== "string") {
        item.isCoverInvalid = true
        invalidCount++
        return resolve()
      }
      const img = new Image()
      img.onload = () => resolve()
      img.onerror = () => {
        item.isCoverInvalid = true
        invalidCount++
        resolve()
      }
      img.src = baseUrl + item.coverUrl.trim()
    })
  }
  for (let i = 0; i < list.length; i += chunkSize) {
    await Promise.all(list.slice(i, i + chunkSize).map(validateCover))
  }
  return invalidCount
}

// 检查所有封面
async function checkCoverInvalid() {
  const data = Array.isArray(tableData.value) ? tableData.value : []
  if (!data.length) return
  const invalidCount = await validateCoverList(data, 5)
  ElMessage[invalidCount ? "warning" : "success"](
    invalidCount ? `共有 ${invalidCount} 个封面无效，请检查！` : "未发现无效封面！"
  )
}

// 演员/系列选项
const actorOptions = ref<{ label: string, value: string }[]>([])
const seriesOptions = ref<{ label: string, value: string }[]>([])

// 获取演员和系列数据
interface ApiResponse<T> {
  data?: {
    list?: T[]
    [key: string]: any
  }
  [key: string]: any
}

async function fetchActorAndSeries() {
  try {
    const [actorRes, seriesRes] = await Promise.all([
      getActorData({}),
      getSeriesData({})
    ]) as [ApiResponse<any>, ApiResponse<any>]
    actorOptions.value = (actorRes?.data?.list ?? []).map(toOption)
    seriesOptions.value = (seriesRes?.data?.list ?? []).map(toOption)
  } catch (error) {
    console.error("获取演员或剧集数据失败:", error)
  }
}

async function handleActorFocus() {
  if (actorOptions.value.length === 0) {
    const res = await getActorData({}) as ApiResponse<any>
    actorOptions.value = (res?.data?.list ?? []).map(toOption)
  }
}

async function handleSeriesFocus() {
  if (seriesOptions.value.length === 0) {
    const res = await getSeriesData({}) as ApiResponse<any>
    seriesOptions.value = (res?.data?.list ?? []).map(toOption)
  }
}

// 重置搜索
function resetSearchData() {
  currentPage.value = 1
  searchParams.value = getSearchParams()
  fetchData()
}
// 搜索
function searchClick() {
  currentPage.value = 1
  fetchData()
}

// 页面初始化
onMounted(() => {
  fetchData()
  fetchActorAndSeries()
})
</script>

<template>
  <div class="view-container">
    <!-- 操作栏 -->
    <div class="view-header">
      <div style="display: flex; gap: 10px;">
        <el-input v-model="searchParams.videoName" placeholder="输入视频名称搜索" clearable />
        <el-select
          v-model="searchParams.actor" filterable allow-create default-first-option :reserve-keyword="false"
          placeholder="请选择主演" clearable @change="fetchData" @focus="handleActorFocus"
        >
          <el-option v-for="item in actorOptions" :key="item.value" :label="item.label" :value="item.value" />
          <el-option label="其他" value="其他" />
        </el-select>
        <el-select v-model="searchParams.videoType" placeholder="请选择类型" clearable @change="fetchData">
          <el-option v-for="item in videoTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-select v-model="searchParams.resolution" placeholder="请选择分辨率" clearable @change="fetchData">
          <el-option v-for="item in resolutionOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-select v-model="searchParams.subtitle" placeholder="请选择字幕类型" clearable @change="fetchData">
          <el-option v-for="item in subtitleOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-select
          v-model="searchParams.series" filterable allow-create default-first-option :reserve-keyword="false"
          placeholder="请选择系列" clearable @change="fetchData" @focus="handleSeriesFocus"
        >
          <el-option v-for="item in seriesOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <div style="flex: 0 0 160px; display: flex; align-items: center; justify-content: space-between;">
          <el-dropdown split-button type="primary" @click="searchClick" @command="resetSearchData">
            <div style="width: 60px;text-align: center;">
              搜 索
            </div>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="reset">
                  重置搜索
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <!-- <el-button style="flex:1" type="success" @click="resetSearchData">重置</el-button> -->
          <!-- <el-button style="flex:1" type="primary" @click="searchClick">搜索</el-button> -->
        </div>
      </div>
      <div>
        <el-checkbox v-model="filterMulti" label="过滤文档多人合作视频在演员分组中的显示" border />
      </div>
      <div>
        <el-button type="primary" @click="showDialog">
          添加视频
        </el-button>
        <el-button type="danger" @click="batchDelete" v-if="checkPermission(['admin'])">
          批量删除
        </el-button>
        <!-- <el-button type="warning" @click="batchAdd">批量添加</el-button> -->
        <el-button type="success" @click="downloadDoc">
          下载文档
        </el-button>
        <el-button type="success" @click="downloadAllDoc">
          下载全部资源
        </el-button>
        <el-button type="primary" @click="checkCoverInvalid">
          检查无效封面
        </el-button>
      </div>
    </div>

    <!-- 列表 -->
    <div class="view-main">
      <el-table :data="tableData" @selection-change="handleSelectionChange" border style="height:100%;width: 100%">
        <el-table-column type="selection" :selectable="selectable" width="55" />
        <el-table-column fixed label="封面" width="180">
          <template #default="{ row }">
            <div>
              <el-image :src="baseUrl + row.coverUrl" />
            </div>
          </template>
        </el-table-column>
        <el-table-column fixed label="名称" width="140">
          <template #default="{ row }">
            <div>
              <span>{{ row.videoName }}</span>
              <el-tooltip
                effect="light" content="未添加封面或封面无效" placement="top"
                v-if="!row.coverUrl || row.isCoverInvalid"
              >
                <el-button type="danger" :icon="WarningFilled" link />
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="releaseDate" label="发行日期" width="140" />
        <el-table-column prop="actor" label="主演" width="240" />
        <el-table-column prop="shortDesc" label="简介" min-width="200">
          <template #default="{ row }">
            <div v-if="row.shortDesc?.length > 30">
              <el-popover trigger="hover" placement="top-start" :width="400">
                <p>{{ row.shortDesc }}</p>
                <template #reference>
                  <div class="ellipsis-two-lines">
                    {{ row.shortDesc }}
                  </div>
                </template>
              </el-popover>
            </div>
            <div v-else>
              <div class="ellipsis-two-lines">
                {{ row.shortDesc }}
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="series" label="系列" width="280" />

        <el-table-column width="200">
          <template #header>
            <span>更多</span>
          </template>
          <template #default="scope">
            <div style="display: flex; gap: 5px;">
              <el-tag type="success" size="small" round v-if="scope.row.resolution !== '1080p'">
                {{ scope.row.resolution }}
              </el-tag>
              <el-tag type="info" size="small" round v-else>
                {{ scope.row.resolution }}
              </el-tag>
              <el-tag type="success" size="small" round v-if="scope.row.videoType !== '有码'">
                {{ scope.row.videoType }}
              </el-tag>
              <el-tag type="info" size="small" round v-else>
                {{ scope.row.videoType }}
              </el-tag>
              <el-tag type="danger" size="small" round v-if="scope.row.subtitle !== '外挂字幕'">
                {{ scope.row.subtitle }}
              </el-tag>
              <el-tag type="info" size="small" round v-else>
                {{ scope.row.subtitle }}
              </el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="120">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="handleEdit(scope.row)">
              编辑
            </el-button>
            <el-button
              link type="danger" size="small" @click="handleRemove(scope.row)"
              v-if="checkPermission(['admin'])"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 分页 -->
    <div class="view-footer">
      <el-pagination
        background layout="total,sizes, prev, pager, next" :total="total"
        v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 50, 100]"
        @current-change="handlePageChange" @size-change="handleSizeChange"
      />
    </div>

    <!-- 添加对话框 -->
    <el-dialog
      v-model="addDialogVisible" :title="isEdit ? '编辑视频' : '添加视频'" :close-on-click-modal="false"
      @close="closeDialog" align-center
    >
      <el-form :model="formData" label-width="100px" :rules="formRules" ref="formDataRef">
        <el-form-item label="名称" prop="videoName">
          <el-input v-model="formData.videoName" />
        </el-form-item>
        <el-form-item label="主演" prop="actorList">
          <!-- <el-input v-model="formData.actor" /> -->
          <el-select
            v-model="formData.actorList" multiple clearable filterable allow-create default-first-option
            :reserve-keyword="false" placeholder="请选择主演" @focus="handleActorFocus"
          >
            <el-option v-for="item in actorOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="简介" prop="shortDesc">
          <el-input v-model="formData.shortDesc" />
        </el-form-item>

        <el-form-item label="封面">
          <div style="width: 100%;">
            <!-- <div style="display: flex; align-items: center; gap: 10px;margin-bottom: 10px;">
            <el-input placeholder="输入图片链接上传" v-model="formData.imageUrl" style="width: 100%;"></el-input>
            <el-button type="success" @click="submitForm(formDataRef, 'imageUpload')">上 传</el-button>
          </div> -->
            <el-upload
              action="" :limit="1" list-type="picture-card" accept=".pdf,.gif,.jpg,.png"
              :on-change="fileChange" :auto-upload="false" v-model:file-list="fileList" :disabled="fileList.length > 0"
            >
              <el-icon>
                <Plus />
              </el-icon>
              <template #file="{ file }">
                <div>
                  <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
                  <span class="el-upload-list__item-actions">
                    <span class="el-upload-list__item-delete" @click="removeFile(file)">
                      <el-icon>
                        <Delete />
                      </el-icon>
                    </span>
                  </span>
                </div>
              </template>
            </el-upload>
          </div>
        </el-form-item>
        <el-form-item label="发行日期" prop="releaseDate">
          <el-date-picker v-model="formData.releaseDate" type="date" value-format="YYYY-MM-DD" />
        </el-form-item>
        <el-form-item label="系列" prop="series">
          <!-- <el-input v-model="formData.series" /> -->
          <el-select
            v-model="formData.series" filterable allow-create default-first-option :reserve-keyword="false" @clear="formData.series = ''"
            placeholder="请选择系列" clearable @focus="handleSeriesFocus"
          >
            <el-option v-for="item in seriesOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>

        <el-form-item label="类型" prop="videoType">
          <el-select v-model="formData.videoType" placeholder="请选择类型">
            <el-option v-for="item in videoTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="分辨率" prop="resolution">
          <el-select v-model="formData.resolution" placeholder="请选择分辨率">
            <el-option v-for="item in resolutionOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="字幕" prop="subtitle">
          <el-select v-model="formData.subtitle" placeholder="请选择字幕类型">
            <el-option v-for="item in subtitleOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label-width="0">
          <div style="width: 100%;display: flex;justify-content: center;gap: 20px;">
            <el-button style="width: 120px;" @click="closeDialog">
              取 消
            </el-button>
            <el-button style="width: 120px;" type="primary" @click="submitForm(formDataRef)">
              提 交
            </el-button>
          </div>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<style scoped></style>
